package com.apache.database.db;

import com.apache.database.constant.Validator;
import com.apache.database.datasource.ConnctionData;
import com.apache.database.datasource.DataSourceAspect;
import com.apache.database.datasource.DynamicDataSource;
import com.apache.database.datasource.DynamicDataSourceHolder;
import com.apache.database.db.hibernate.DaoHibernateImpl;
import com.apache.database.db.ibatis.DaoIbatisImpl;
import com.apache.database.db.ibatis.DiclectStatementHandlerInterceptor;
import com.apache.database.exception.DaoAccessException;
import com.apache.database.model.MethodParam;
import com.apache.database.model.Page;
import com.apache.license.validator.LicenseValidate;
import com.apache.license.validator.OsUtils;

import java.util.List;

/**
 * description: 持久层的实现 可以重写此类的方法来满足特定的业务要求
 * 
 */
public abstract class DaoImpl implements IDao {

	protected DaoHibernateImpl hibernateDao;

	protected DaoIbatisImpl ibatisDao;

	protected boolean isHibernateDao() {//判断是启用Hibernate还是ibatis
		//判断lisense是否有效
		if (LicenseValidate.getInstance().isInitMark() && !LicenseValidate.getInstance().isEffective()) {
			throw new DaoAccessException("ORA-ls10001    Local MAC address "+OsUtils.getMacAddress()+" is not authorized or lisence has expired!");
		}
		if (Validator.isEmpty(ibatisDao)) {//启用hibernate
			return true;
		}
		return false;//启用myibatis
	}

	public void setHibernateDao(DaoHibernateImpl hibernateDao) {
		this.hibernateDao = hibernateDao;
	}

	/* (non-Javadoc)
	 * @see com.persistenceLayer.core.db.IDao#count(com.persistenceLayer.core.model.MethodParam)
	 */
	public long count(MethodParam param) {
		if (isHibernateDao()) {
			return hibernateDao.count(param);
		} else
			return ibatisDao.count(param);
	}

	/* (non-Javadoc)
	 * @see com.persistenceLayer.core.db.IDao#delete(com.persistenceLayer.core.model.MethodParam)
	 */
	public boolean delete(MethodParam param) {
		setMethodParam(param);
		if (isHibernateDao()) {
			return hibernateDao.delete(param);
		} else
			return ibatisDao.delete(param);
	}

	/* (non-Javadoc)
	 * @see com.persistenceLayer.core.db.IDao#deleteBath(com.persistenceLayer.core.model.MethodParam)
	 */
	public boolean deleteBath(MethodParam param) {
		setMethodParam(param);
		if (isHibernateDao()) {
			return hibernateDao.deleteBath(param);
		} else
			return ibatisDao.deleteBath(param);
	}

	/* (non-Javadoc)
	 * @see com.persistenceLayer.core.db.IDao#edit(com.persistenceLayer.core.model.MethodParam)
	 */
	public boolean edit(MethodParam param) {
		setMethodParam(param);
		if (isHibernateDao()) {
			return hibernateDao.edit(param);
		} else
			return ibatisDao.edit(param);
	}

	/* (non-Javadoc)
	 * @see com.persistenceLayer.core.db.IDao#editBath(com.persistenceLayer.core.model.MethodParam)
	 */
	public boolean editBath(MethodParam param) {
		setMethodParam(param);
		if (isHibernateDao()) {
			return hibernateDao.editBath(param);
		} else
			return ibatisDao.editBath(param);
	}

	/* (non-Javadoc)
	 * @see com.persistenceLayer.core.db.IDao#insert(com.persistenceLayer.core.model.MethodParam)
	 */
	public boolean insert(MethodParam param) {
		setMethodParam(param);
		if (isHibernateDao()) {
			return hibernateDao.insert(param);
		} else
			return ibatisDao.insert(param);
	}

	/* (non-Javadoc)
	 * @see com.persistenceLayer.core.db.IDao#insertBath(com.persistenceLayer.core.model.MethodParam)
	 */
	public boolean insertBath(MethodParam param) {
		setMethodParam(param);
		if (isHibernateDao()) {
			return hibernateDao.insertBath(param);
		} else
			return ibatisDao.insertBath(param);
	}

	/* (non-Javadoc)
	 * @see com.persistenceLayer.core.db.IDao#pageSelect(com.persistenceLayer.core.model.MethodParam)
	 */
	public Page pageSelect(MethodParam param) {
		if (isHibernateDao()) {
			return hibernateDao.pageSelect(param);
		} else
			return ibatisDao.pageSelect(param);
	}

	/* (non-Javadoc)
	 * @see com.persistenceLayer.core.db.IDao#select(com.persistenceLayer.core.model.MethodParam)
	 */
	public List select(MethodParam param) {
		if (isHibernateDao()) {
			return hibernateDao.select(param);
		} else
			return ibatisDao.select(param);
	}

	/* (non-Javadoc)
	 * @see com.persistenceLayer.core.db.IDao#selectSingle(com.persistenceLayer.core.model.MethodParam)
	 */
	public Object selectSingle(MethodParam param) {
		if (isHibernateDao()) {
			return hibernateDao.selectSingle(param);
		} else
			return ibatisDao.selectSingle(param);
	}

	/* (non-Javadoc)
	 * @see com.ius.database.db.IDao#selectById(com.ius.database.model.MethodParam)
	 */
	public Object selectById(MethodParam param) {
		if (isHibernateDao()) {
			return hibernateDao
					.selectById(param.getSpanceName(), param.getKey(), param.getInfoId(), param.getCacheId());
		} else
			return ibatisDao.selectById(param.getSpanceName(), param.getKey(), param.getInfoId(), param.getCacheId());
	}

	public void setIbatisDao(DaoIbatisImpl ibatisDao) {
		this.ibatisDao = ibatisDao;
	}

	private void setMethodParam(MethodParam param){
		if(Validator.isNull(String.valueOf(param.getParamsByKey("datasource")))){
			String datasourceType= DiclectStatementHandlerInterceptor.getDataSourceType();
			if(Validator.isNull(datasourceType)) {
				String sysName = Validator.getDefaultStr(DynamicDataSourceHolder.getDataSouce(),
						DynamicDataSource.getInstance().getDefaultDataSourceKey());
				datasourceType =ConnctionData.getInstance().getDataBaseType(null,"",sysName);
			}
			param.setParams("datasource_type",datasourceType);
		}else{
			String datasourceType =ConnctionData.getInstance().getDataBaseType(null,"",param.getParamsByKey("datasource").toString());
			param.setParams("datasource_type",datasourceType);
		}
	}

}
